# -*- coding: utf-8 -*-
"""
===============================
@Author     : Zuo WenTao
@Time       : 2024/5/30 9:49
@Description: 监控某一个函数执行时间,支持多线程调用
@Change     : v2
@File       : MonitoredFuncThread.py
===============================
"""
import random
import threading
import queue
import time

from concurrent.futures import ThreadPoolExecutor, as_completed


class FunctionTimeoutError(Exception):
    pass


def func_wrapper(func, q, *args, **kwargs):
    try:
        result = func(*args, **kwargs)
        q.put(result)
    except Exception as e:
        q.put(e)


def monitored_func(func, timeout):
    def wrapper(*args, **kwargs):
        result_queue = queue.Queue()

        def target():
            try:
                result = func(*args, **kwargs)
                result_queue.put(result)
            except Exception as e:
                result_queue.put(e)

        thread = threading.Thread(target=target)
        thread.start()
        thread.join(timeout)

        if thread.is_alive():
            raise FunctionTimeoutError(f"函数 '{func.__name__}' 超过了执行的超时时间 {timeout} 秒")

        result = result_queue.get()
        if isinstance(result, Exception):
            raise result

        return result

    return wrapper


if __name__ == '__main__':
    def example_func(data):
        # time.sleep(random.randint(0, 5))
        time.sleep(100)
        return data


    result_box = []
    task_list = []
    with ThreadPoolExecutor(max_workers=10) as t:
        for i in range(10):
            monitored_func_with_timeout = monitored_func(example_func, 1)
            data = "Function executed successfully!"
            task_list.append(t.submit(monitored_func_with_timeout, data))
    for result in as_completed(task_list):
        try:
            result = result.result()
            result_box.append(result)
        except FunctionTimeoutError as e:
            pass
        except Exception as e:
            print(f"任务执行出错：{e}")

    print(result_box)
